package org.budo.support.spring.web.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.budo.support.lang.util.ListUtil;
import org.budo.support.lang.util.ReflectUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author limingwei
 */
public class RequestMappingUtil {
    private static final Boolean HAS_GET_MAPPING = ReflectUtil.hasClass("org.springframework.web.bind.annotation.GetMapping");

    public static String[] requestMappingPath(Method method) {
        // 不用 AnnotationUtils.findAnnotation 因为里面可能有 注解之注解 等逻辑
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (null != requestMapping) {
            return requestMapping.value();
        }

        if (HAS_GET_MAPPING) {
            GetMapping getMapping = method.getAnnotation(GetMapping.class);
            if (null != getMapping) {
                return getMapping.value();
            }

            PostMapping postMapping = method.getAnnotation(PostMapping.class);
            if (null != postMapping) {
                return postMapping.value();
            }
        }

        return null;
    }

    public static List<String> getRequestMapping(Method method) {
        String[] methodMappings = requestMappingPath(method);

        RequestMapping classAnnotation = method.getDeclaringClass().getAnnotation(RequestMapping.class);
        if (null == classAnnotation) {
            return ListUtil.toList(methodMappings);
        }

        String[] classMappings = classAnnotation.value();
        if (null == classMappings || classMappings.length < 1) {
            return ListUtil.toList(methodMappings);
        }

        // 方法上未指定 url ，用 类上的
        if (null == methodMappings) {
            return ListUtil.toList(classMappings);
        }

        List<String> mappings = new ArrayList<String>();

        // 方法和类上都有
        for (String classMapping : classMappings) {
            for (String methodMapping : methodMappings) {
                String linker = classMapping.endsWith("/") || methodMapping.startsWith("/") ? "" : "/";
                mappings.add(classMapping + linker + methodMapping);
            }
        }

        return mappings;
    }
}